home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 32 / Amiga Format AFCD32 (Nov 1998, Issue 117).iso / -seriously_amiga- / programming / basic / blitzc2p / blitzc2p.readme next >
Text File  |  1998-08-10  |  22KB  |  437 lines

  1.  
  2. This is a collection of fast chunky-to-planar routines implemented into blitz
  3. basic for use in any software including commercial and shareware.
  4.  
  5. There are five standard c2p's which have two versions, one to do a normal c2p
  6. operation and the other to do c2p as well as a clearscreen at the same time
  7. (25-30% faster than seperate clearscreen). There is a sixth c2p that is of a
  8. different design and has special requirements.
  9.  
  10. c2p030only   : Only for use on 68030 cpu's. For 68030 users, this c2p
  11.                will perform better than all the others.
  12.  
  13. c2p030onlyCLS: As above, except that it also clears (to a given longword)
  14.                the chunky buffer that it has just read data from.
  15.  
  16. c2p040only   : Only for use on 68040 cpu's, but performs very well on
  17.                anything higher. For 68040 users, this c2p will perform
  18.                better than all the others.
  19.  
  20. c2p040onlyCLS: As above, except that it also clears (to a given longword)
  21.                the chunky buffer that it has just read data from.
  22.  
  23. c2p060only   : Only for use on 68060 cpu's. It is not, however, the fastest
  24.                and you will find that c2p040only and c2pCACHE are faster.
  25.                Probably does not perform very well on anything lower than
  26.                an 060.
  27.  
  28. c2p060onlyCLS: As above, except that it also clears (to a given longword)
  29.                the chunky buffer that it has just read data from.
  30.  
  31. c2pGeneric   : A generic c2p for use on all cpu's if it is not possible
  32.                to isolate the cpu model or to use seperate c2p's for
  33.                different cpu's. Performs well on 030 but is somewhat slower
  34.                than dedicated routines on higher processors. Mainly to provide
  35.                support for 030, as higher processors will be crippled.
  36.  
  37. c2pGenericCLS: As above, except that it also clears (to a given longword)
  38.                the chunky buffer that it has just read data from.
  39.  
  40. c2p040plus   : A kind of generic routine for 040 or higher. Performs generally
  41.                quite well on all 040 and 060 cpu's but is not as fast as
  42.                dedicated c2p's. Not suitable for 030's.
  43.  
  44. c2p040plusCLS: As above, except that is also clears (to a given longword)
  45.                the chunky buffer that it has just read data from.
  46.  
  47. c2pCACHE     : Designed for use on anything from a 68040 upwards. Second
  48.                fastest on 040/25 but joint fastest on 060/50. Perhaps more
  49.                geared towards 68060 than anything lower. This c2p is less
  50.                flexible and requires special treatment.
  51.  
  52. c2pCACHECLS  : This does not exist as it is not possible to meddle with the
  53.                way that the routine specially handles datacaches, which would
  54.                result if there were any additional writing to memory such
  55.                as when a clearscreen is performed.
  56.  
  57. Some general performance times for the routines are as follows. These times
  58. are inclusive of having a screen open and being displayed, of the specified
  59. dimensions (* indicates best suitability for the given c2p):
  60.  
  61. c2p030only   : On 68030/50Mhz PAL
  62. 68030 only   * 320x200 @40.4fps
  63.              * 320x256 @30.7fps
  64.  
  65.                On 68040/25Mhz DoublePAL
  66.                320x200 @42fps
  67.                320x256 @31fps
  68.  
  69.                On 68040/25Mhz PAL
  70.                320x200 @44fps
  71.                320x256 @36.5fps
  72.  
  73. c2p030onlyCLS: On 68040/25Mhz PAL
  74. 68030 only     320x200 @38.5fps
  75.                320x256 @29.7fps
  76.  
  77.  
  78. c2p040only   : On 68030/50Mhz PAL
  79. 68040          320x200 @28.2fps
  80. to             320x256 @21.6fps
  81. 68060
  82.  
  83.                On 68040/25Mhz DoublePAL
  84.              * 320x200 @49.6fps
  85.              * 320x256 @36.2fps
  86.  
  87.                On 68040/25Mhz PAL
  88.              * 320x200 @55.3fps
  89.              * 320x256 @42.5fps
  90.  
  91.                On 68060/50Mhz PAL
  92.              * 320x200 @66.1fps
  93.              * 320x256 @50fps
  94.  
  95. c2p040onlyCLS: On 68040/25Mhz PAL
  96. 68040        * 320x200 @49fps (seperate clearscreen ran about 45-46fps)
  97. to           * 320x256 @37.1fps
  98. 68060
  99.  
  100. c2p060only   : On 68030/50Mhz PAL
  101. 68060 only     320x200 @27.9fps
  102.                320x256 @21.5fps
  103.  
  104.                On 68040/25Mhz DoublePAL
  105.                320x200 @46.0fps
  106.                320x256 @34.2fps
  107.  
  108.                On 68050/25Mhz PAL
  109.                320x200 @48.2fps
  110.                320x256 @37.4fps
  111.  
  112.                On 68060/50Mhz PAL
  113.              * 320x200 @66fps
  114.              * 320x256 @50fps
  115.  
  116. c2p060onlyCLS: On 68040/25Mhz PAL
  117. 68060 only     320x200 44.5fps
  118.                320x256 33.8fps
  119.  
  120.  
  121. c2pGeneric   : On 68030/50Mhz PAL
  122. all, but     * 320x200 @40.1fps
  123. mainly 68030 * 320x256 @30.7fps
  124.  
  125.                On 68040/25Mhz DoublePAL
  126.                320x200 @42fps
  127.                320x256 @31fps
  128.  
  129.                On 68040/25Mhz PAL
  130.                320x200 @44fps
  131.                320x256 @34fps
  132.  
  133. c2pGenericCLS: On 68040/25Mhz PAL
  134. all, but       320x200 @38.8fps
  135. mainly 68030   320x256 @29.7fps
  136.  
  137.  
  138. c2p040plus   : On 68030/50Mhz PAL
  139. 68040          320x200 @24.3fps
  140. to             320x256 @18.5fps
  141. 68060
  142.                On 68040/25Mhz DoublePAL
  143.              * 320x200 @46fps
  144.              * 320x256 @34.2fps
  145.  
  146.                On 68040/25Mhz PAL
  147.              * 320x200 @49.2fps
  148.              * 320x256 @37.9fps
  149.  
  150.                On 68060/50Mhz PAL
  151.              * 320x200 @66fps
  152.              * 320x256 @50fps
  153.  
  154. c2p040plusCLS: On 68040/25Mhz PAL
  155. 68040        * 320x200 @45.6fps
  156. to           * 320x256 @35fps
  157. 68060
  158.  
  159.  
  160. c2pCACHE     : On 68030/50Mhz PAL
  161. 68040          320x200 @23.5fps
  162. to             320x256 @18.0fps
  163. 68060
  164.  
  165.                On 68040/25Mhz DoublePAL
  166.              * 320x200 @47.1fps
  167.              * 320x256 @35.3fps
  168.  
  169.                On 68040/25Mhz PAL
  170.              * 320x200 @50fps
  171.              * 320x256 @38.3fps
  172.  
  173.                On 68060/50Mhz PAL
  174.              * 320x200 @66.1fps
  175.              * 320x256 @49.6fps
  176.  
  177.  
  178. For 68030 owners, do not use c2p040plus, c2p040only, c2p060only, or c2pCACHE.
  179. These will give very bad performance on that cpu.
  180.  
  181. All of the routines except for c2pCACHE allow you to specify the size of the
  182. chunky-to-planar operation by way of a c2pRoutineInit{} statement, where
  183. `Routine' is the name of the routine (e.g. c2p040onlyInit{}). If you alter the
  184. size of the c2p operation you should generally also alter the size of your planar
  185. destination bitmap to be equal.
  186.  
  187. It is, however, possible to have a taller planar bitmap than the height of the
  188. chunky-to-planar operation. #c2pBPLSIZE has to be altered to reflect this. The
  189. planar height must always be equal to or greater than the chunky height.
  190.  
  191. Each c2p routine has two inputs. The first parameter is the address of the chunky
  192. buffer and the second parameter is the address of the planar buffer. Planar
  193. memory must be contiguous so I suggest initialising a bank or reserving some
  194. memory, and then using CludgeBitmap. The inputs to the init statements are the
  195. width and height of the chunky buffer, hense the size of the c2p operation.
  196. The init routine only needs to be called once in a program for any number of c2p
  197. calls.
  198.  
  199. c2pCACHE is different in that you must specify operation size in constants which
  200. cannot easily be altered during the running of the program, so you are restricted
  201. to one size of operation per program run.
  202.  
  203. All you have to do to setup a c2p operation is something along these lines (for
  204. example):
  205.  
  206. InitBank 2,320*256,$10000 ; Fastram chunky buffer
  207. InitBank 0,320*256,$10002 ; Chipram planar buffer
  208. CludgeBitmap 0,320,256,8,Bank(0)
  209. c2pGenericInit{320,256}
  210. c2pGeneric{Bank(2),Bank(0)}
  211.  
  212. Of course, replace the c2pGeneric statements with the ones for the relevent c2p
  213. that you are using.
  214.  
  215. The only exception to this is c2pCACHE. This requires that you cludge bitmaps to
  216. 8 bytes past the start of the planar buffer, and that you tell the c2pCACHE
  217. routine to output to an address 4 bytes past the start of the planar buffer. So
  218. you have to allow for this by reserving a little extra memory. Like
  219. this:
  220.  
  221. InitBank 2,320*256,$10000 ; Fastram chunky buffer
  222. InitBank 0,(320*256)+8,$10002 ; Chipram planar buffer
  223. CludgeBitmap 0,320,256,8,Bank(0)+8
  224. c2pCACHE{Bank(2),Bank(0)+4}
  225.  
  226. As well as c2pCACHE having to be set up with constants, there is also no
  227. clearscreen version because it is not possible to implement it due to the nature
  228. of the way the c2p works.
  229.  
  230. Generally you should ensure that the base address of a planar bitmap's bitplane
  231. data is aligned to the nearest 64 pixels. Reserving some memory with AllocMem or
  232. InitBank usually seems to do this very reliably. c2pCACHE requires that you
  233. create bitmaps at 8 bytes past the start of the data, and that you begin the c2p
  234. operation at 4 bytes past the start. This is to ensure that the data being
  235. displayed is 64-bit aligned otherwise you would get a lower datafetch.
  236.  
  237. In amigamode, if the first longword of data that is being displayed is from a
  238. 64-bit aligned address, the o/s will use 64-bit datafetch which means faster
  239. chunky-to-planar conversion. If you begin to scroll the display with hardware
  240. scrolling and you go beyond 32 pixels, the first longword being displayed will no
  241. longer be 64-bit aligned, and so the o/s will automatically switch to fetchmode 1
  242. or 2 (32-bit datafetch), which will slow down the c2p. More horrifically, the o/s
  243. will not use normally use fetchmode 0 but YOU should make sure that if you set
  244. the datafetch you do NOT use datafetch 0 because that will at least double the
  245. time it takes to do the c2p operation, and that is bad news.
  246.  
  247. To do scrolling with chunky screens it is not normally the best idea to use
  248. hardware scrolling. The c2p's do not have a line modulo so you would have to make
  249. your planar bitmap 64 pixels wider which means a further 64x200 or 64x256 area to
  250. be converted. This is also a waste because one longword in chunky is only 4
  251. pixels, so a harware scroll of 0..3 is normally all that is requires. So the
  252. remaining 60 pixels are a total waste. As such, I recommend using software
  253. scrolling and generally speaking, if you have enough power to use
  254. chunky-to-planar well then you should also be thinking of refreshing the whole
  255. screen every frame rather than any of the traditional scroll methods. Taking a
  256. leap to using chunky is also to take a leap towards other factors which come as
  257. part of the package. Screens are normally fully refreshed each frame, scrolling
  258. is done in software, blits are done with the cpu and generally there is cpu
  259. horsepower to back this all up. 030/50's are generally going to be a little
  260. limited in what can be achieved with a decent screensize. I suggest 040/25 is the
  261. entry-level for chunky-to-planar equipped software, unless you have direct output
  262. to a graphics card which does not therefore require any data-conversion.
  263.  
  264. For a purely generic setup, use the c2pGeneric routine. It will, however, be
  265. quite crippling to 040 or 060 processors but will better support the low end. To
  266. take things one stage further, use also c2p040plus which is a generic routine for
  267. 040-060 cpu's. To take it to the next level you should be looking to have a
  268. specific routine for each cpu. For 030's use c2p030only and for 040's use
  269. c2p040only. It seems that c2p040only is actually faster than c2p060only when
  270. running on a 68060/50, but there is hardly anything in it so take your pick.
  271. c2pCACHE is another replacement possibility for c2p040plus and is faster but less
  272. flexible. Certainly you don't need to support ALL of the c2p's in your software
  273. as there is quite a lot of overlap and it may come down to personal taste.
  274.  
  275. Personally I would use c2p030only for anything below 040, and c2p040only for
  276. anything from 040upwards. If I had to choose ONE generic c2p I would go for
  277. c2p040plus as it performs slighter better than c2pCACHE when used on 030's,
  278. although either of them on 030 are pretty poor, so I would generally target the
  279. software at 040 upwards.
  280.  
  281. Generally speaking, the clearscreen routines save you between 3 and 5 frames per
  282. second compared with having to do a seperate clearscreen routine. Time is mainly
  283. gained by minor pipelining and the fact that the c2p routine is already handling
  284. and setting up the loop. All that has been done to facilitate the clearscreen is
  285. that (in most cases) a7 is loaded with #clearscreento, which is a longword, and
  286. then move.l (a0)+,Dn is converted to move.l (a0),Dn : move.l a7,(a0)+ ; or if it
  287. is the 030only or generic routine, then it has been converted to move.l (a0),Dn :
  288. move.l #clearscreento,(a0)+, because those routines do not have a7 spare.
  289.  
  290. It is possible to do a screencopy at the same time as the c2p, but this is not
  291. feasible on c2p030only or c2pGeneric as there needs to be a spare register.
  292. Therefore, a screencopy in place of the clearscreen (which will also do the same
  293. thing as a clearscreen, effectively) is only viable on 040 upwards, and judging
  294. by the time it takes it may be better suited to 060 only. It is therefore
  295. suggested that it might be faster to do a seperate screencopy which is perhaps
  296. hardcoded and may use move16, which may equal or surpass the time that might be
  297. saved by doing the screencopy at the same time as the c2p. I HAVE done a
  298. screencopy test using c2p040only, in which move.l (a0)+,Dn has been converted to
  299. move.l (a0),Dn : move.l (a7)+,(a0)+ ; and it seems to perform @44.3fps for
  300. 320x200, or 34.1fps for 320x256 (040/25 results). This is an extra 3 frames per
  301. second on top of the c2pCLS time, or about 9-10fps for the copy compared with a
  302. c2p that does not do anything additional (c2p040only). If you can do a screencopy
  303. seperately, perhaps using movem or move16, faster than this on 040/25, then I
  304. suggest you do that rather than modify the c2p. Judging by the time it takes and
  305. the number of chunky blits it gobbles up I would suggest that fullscreen copy is
  306. not very viable on anything lower than 040 and is probably questionable on
  307. 040/25.
  308.  
  309. If you have a horizontal strip at the top or bottom or even middle of your
  310. display that does not need to be clearscreened and yet is updated a lot, use a
  311. clearscreening c2p for the main game area and a non-clearscreening one for the
  312. panel area.
  313.  
  314. When it comes to chunky blitting you need to take into account the processor you
  315. are working on. If you have anything from 68040 upwards it is faster to have mask
  316. data (same size as the graphic) and to write longwords to non-aligned addresses,
  317. than to try generating the mask on-the-fly. The code: move.l (a2)+,d0 : move.l
  318. d0,(a1) : move.l (a0)+,d1 : move.l d1,(a1)+ ; will do one longword of masked blit
  319. to anywhere on the screen, about 2-3 times faster than if you try to generate the
  320. mask from the source data. Also, writing to byte addresses is probably not
  321. supported on 68000, I'm not sure about 68020. But if you do it with a copyback
  322. cache it is very quick, so that masked blits are only about 30% slower than
  323. unmasked ones. If you are not going to write to non-aligned addresses you have to
  324. do shifting or rotating in the cpu, which if using mask data means the mask as
  325. well. This takes further time. But these memory-intensive methods may not prove
  326. to be quite so efficient on 030's as they do not have a copyback cache.
  327.  
  328. I did not write any of the c2p's myself, only the minor modifications and the
  329. example program. You are free to use them all in any of your productions,
  330. freeware, shareware, and even commercialware. I hope you are thankful to those
  331. talented few that have mastered their craft in making these c2p's and for
  332. releasing them for public use.
  333.  
  334. Please find also enclosed in this archive a demonstration program. There is an
  335. 040 version for 040-to-060, and an 030 version. This program will use a
  336. clearscreening c2p and will bounce a number of chunky cpu-blitted objects around
  337. the screen. The blit routines do not do any clipping and the loop for movement
  338. and rendering of the objects is currently hardcoded into a single statement. This
  339. is quite a bit faster than calling a statement for every object.
  340.  
  341. There are some constants which you can alter. The demonstration program has the
  342. facility to have a planar bitmap height larger than the chunky bitmap height. You
  343. must not allow it to be smaller, however! #planarheight should be >= #c2pBPLY.
  344. If you use: #c2pBPLY=200 : #planarheight=256 ; the routine will do a c2p
  345. operation on the first 200 lines and leave the bottom 56 lines as they are. This
  346. shows how you can use the verticle modulo should you need to.
  347.  
  348. There are other constants to alter. #iterations is how many loops will be done
  349. before the program exits. #objcount is the number of cpu-blit objects that will
  350. be moved and drawn. Refer to the example 040/25 results for guidelines as to what
  351. to set this at. #objwidth and #objheight are the size of the objects. They must
  352. not be larger than the size of the chunky buffer and preferably should be at
  353. least about 16 pixels smaller in both dimensions for the movement routine to work
  354. properly. #objwidth must be a multiple of 4 and must not be smaller than 4.
  355. #objheight does not need to be a multiple of anything but must not be smaller
  356. than 1. The routine currently has constants which will render 85 32x32 256-colour
  357. masked objects with a screen size of 320x240. You should use PAL as preferable to
  358. DoublePAL if you want a higher framerate. 320x200 will yield even higher results.
  359. If you alter the chunky height don't forget about the planarheight.
  360.  
  361. #objmasking should be set to either 0 or nonzero, which means you can use
  362. anything other than 0 (1, -1, 20, -50, etc). If zero, there will be no masking
  363. performed and you will attain higher output, but all objects will be solid. If
  364. objmasking is nonzero, there will be masking and any zero pixels will be
  365. transparent. The routine will default to using masking. The mask routine
  366. uses a prerendered mask image, similar to planar masks, except that it is a byte
  367. for every pixel. This is unavoidable if there is to be such speedy processing. It
  368. is perfectly feasible to generate the mask different to the graphic data so that
  369. any number of colours will be transparent. Don't forget that if you specify an
  370. area as solid when it is blank in the graphic, the blank pixel will be drawn.
  371.  
  372. There is very little difference between the masked and unmasked routines. You
  373. will notice that the masked routine could be simplified as and.l (a2)+,(a1) :
  374. or.l (a0)+,(a1)+ ; but this is illegal in 68000 so I have had to expand it a
  375. little. Currently both routines will allow total flexibility in terms of width
  376. and height (width to nearest 4 pixels), and so use an x loop nested inside a y
  377. loop. If you expand the x loop for a hardcoded version you will get more output,
  378. and similarly with the y loop, although hardcoded large objects take up too much
  379. space to work in cache. Whereas it is possible to do 900 8x8 masked objects on
  380. 040/25, it is possible to do 1100 if the routine is hardcoded for 8x8 with both
  381. loops fully unfolded (ie no loops). The larger the objects you use the less
  382. intermediary time is used in setting them up. Lots of small objects take a lot of
  383. processing of the movement table. Typically, there is time to do about two and a
  384. half 320x200 screenfulls of blitting in the time left after the clearscreening
  385. c2p, on 040/25. The objects that the demoroutine uses are generated when you run
  386. the program so they are only basically random pixels and the palettes are fairly
  387. random too.
  388.  
  389. I have also added a second demo program, which is the same as the first except
  390. that it is dynamic in the number of objects that it displays. You set it a target
  391. frames-per-second rate that you want to know results for. You tell it how many
  392. objects to start off with (must be greater than 0) and how many objects to add
  393. each time (greater than 0). Iterations in the second demo represent how many
  394. loops to do before adding more objects, and this should not be too low or the
  395. routine won't work out wether it's reached the target framerate properly or not.
  396. You have to set a maximum number of objects, because the table has to be
  397. initialised for the eventuality of that many objects becoming displayed. I set it
  398. to 3000 initially which is more than enough for most usual object sizes on all
  399. cpu's.
  400.  
  401. There are versions of the demo for 030 and for 040(+) as before. You set the
  402. program running and it will progressively add objects and move them and will
  403. keep doing so until it reaches the target framerate. Then it will tell you what
  404. precicely the framerate was at the end and how many objects it managed to display
  405. at that rate. So instead of having to do tests on some constant number of
  406. objects, you can let the routine chug away adding more and more until you are
  407. maxxed out for the selected framerate. The demo will default to doing 16x16
  408. objects, starting with 10, and adding 10 more ever 40 loops. You can set the
  409. starting number of objects (objcount) to a value much closer to what you expect
  410. will be the end result, in order to hasten the report. The starting number of
  411. objects should never excede the maximum number, however, or it will probably
  412. start drawing objects everywhere in memory (65536x65536!).
  413.  
  414. Unless you are particularly fussy you do NOT need to have a planar doublebuffer
  415. when using the c2p's, so long as they are running quite fast, ie that the overall
  416. routine is not slowing below 25fps, or not much anyway. There will be a slight
  417. flicker on one or two lines of the display, perhaps, but it will not be the
  418. full-screen type of flickering that you can get on planar. Yes, the c2p's are
  419. outputting to planar but the way they do it seems to minimise flicker. I
  420. personally do not use a doublebuffer and I hardly notice that I haven't. When
  421. you're in the middle of all the action you won't notice either so long as things
  422. don't slow down too much. Even if the overall routine slows down the c2p will
  423. still take the same amount of time so it should be okay. So you can probably cut
  424. out the time it takes to do screen swapping or other doublebuffer methods. Of
  425. course, if you have a graphics card, it is fairly normal to refresh straight into
  426. the display and people have reported that there is little or no flicker
  427. whatsoever.
  428.  
  429. I would be interested to know how any of these routines perform on your
  430. specification of Amiga, and particularly how well the clearscreening c2p's do on
  431. 68060's, ie, does it clearscreen `for free'. Problems or ideas, give me a yell.
  432.  
  433. If you get any problems implementing or using or adapting or modifying the
  434. routines, email at paul@stationone.demon.co.uk
  435.  
  436. Enjoy.
  437.